package org.doubango.ngn.media

import android.content.Context
import android.hardware.Sensor
import android.hardware.SensorEvent
import android.hardware.SensorEventListener
import android.hardware.SensorManager
import org.doubango.ngn.NgnApplication

/** 自定义的重力传感器，用于监控执法仪摄像头是转到后面去了还是前面去了。 */
class GravitySensor: SensorEventListener {

    private val sensorManager = NgnApplication.getContext().getSystemService(Context.SENSOR_SERVICE) as SensorManager
    private var gravitySensor: Sensor? = null
    /** 传感器回调，Int参数为旋转角度（真实视频画面的旋转角度），Boolean参数指定是否需要把预览画面（不是真实画面）旋转180度，true为旋转180度，false为旋转0度*/
    private lateinit var callback: (Int, Boolean) -> Unit?
    private var x = 0f
    private var y = 0f
    private var z = 0f
    private var orientation = 180

    /** 启动重力传感器数据捕捉 */
    fun start(callback: (Int, Boolean) -> Unit?) {
        this.callback = callback
        if (gravitySensor == null) {
            gravitySensor = sensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY)
            sensorManager.registerListener(this, gravitySensor, SensorManager.SENSOR_DELAY_NORMAL)
        }
    }

    /** 停止重力传感器数据捕捉 */
    fun stop() {
        if (gravitySensor != null) {
            sensorManager.unregisterListener(this, gravitySensor)
            gravitySensor = null
        }
    }

    /** 当所登记的传感器的精确度已经改变时调用。*/
    override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {

    }

    /** 当有新的传感器的事件时调用 */
    override fun onSensorChanged(event: SensorEvent) {
        // values[0]为x轴的值，values[1]为y轴的值，values[2]为z轴的值
        // 手机水平放置，手机背面朝下，正面f
        // 当手机左右倾斜时x轴发生改变
        // 当手机上下倾斜时y轴发生改变
        // 当手机由正面翻转到背面时z轴发生改变
        x = event.values[0]
        y = event.values[1]
        z = event.values[2]
        //Timber.i("x = $x, y = $y, z = $z")
        //callback(event.values[1] < 0) // 摄像头向上居中位置为Y值0或者负数，再往后转为正数，往前转为负数

        when {
            // 先判断手机x轴是否处于手机横屏状态，否则按竖屏处理
            x > 7 -> {  // 几乎向左倾斜90度
                orientation = 270
                callback(orientation, false)
            }
            x < -7 -> {
                orientation = 90 // 几乎向右倾斜90度
                callback(90, false)
            }
            y > -4 && y < 4 && z > 7 -> {
                callback(orientation, false) // 水平放置时，保持原来的旋转角度，且禁止预览画面旋转180度
            }
            event.values[1] > 0  -> {
                orientation = 0
                callback(0, false)
            }
            else -> {
                orientation = 180
                callback(180, true)
            }
            // 注：对于values[2]的判断是用于判断手机是否处于水平平放的状态了（即手机背部或屏幕面向天空的状态），此时无法知道手机是向左还是向右倾斜，所以旋转的
            // 角度就和最后一次的保持一样就可以了，水平状态时不需要变来变去的
        }

    }

}